import { def } from './utils'

// 得到Array.prototype
const arrayPrototype = Array.prototype

// 暴露以Array.prototype为原型创建arrayMethods对象
export const arrayMethods = Object.create(arrayPrototype)

// 要被改写的数组方法
const methodsNeedChange = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse',
]

methodsNeedChange.forEach((methodName) => {
  // 备份原来的方法
  const original = arrayPrototype[methodName]
  // 定义新方法
  def(
    arrayMethods,
    methodName,
    function () {
      // 把这个数组身上的__ob__取出来，__ob__已经添加了？因为数组肯定不是最高层，
      // 比如obj.g的属性是数组，第一次遍历obj这个对象的第一层的时候，已经给g属性（这个数组）添加了__ob__属性
      // 定义新的方法(下面参数函数部分不能用箭头-会影响this)
      const ob = this.__ob__

      // 有三种方法push/unshift/splice能够插入新项，现在要把插入的新项也要变为onserve的
      let inserted = []
      // 把类数组对象变成数组
      const args = [...arguments]
      switch (methodName){
        case 'push':
        case 'unshift':
          inserted = args
          break;
        case 'splice':
          // splice个数是splice(下标，数量，插入的新项)
          inserted = args.slice(2)
          break;
      }
      // 判断有没有要插入的新项,让新项也变为响应的
      if(inserted){
        ob.observeArray(inserted)
      }
      ob.dep.notify()
      // 恢复原函数的功能
      const result = original.apply(this, arguments)
      console.log('array')
      return result
    },
    false
  )
})
